home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / distutils / text_file.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  11KB  |  301 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''text_file
  5.  
  6. provides the TextFile class, which gives an interface to text files
  7. that (optionally) takes care of stripping comments, ignoring blank
  8. lines, and joining lines with backslashes.'''
  9. __revision__ = '$Id: text_file.py,v 1.15 2002/11/14 02:25:41 akuchling Exp $'
  10. from types import *
  11. import sys
  12. import os
  13. import string
  14.  
  15. class TextFile:
  16.     '''Provides a file-like object that takes care of all the things you
  17.        commonly want to do when processing a text file that has some
  18.        line-by-line syntax: strip comments (as long as "#" is your
  19.        comment character), skip blank lines, join adjacent lines by
  20.        escaping the newline (ie. backslash at end of line), strip
  21.        leading and/or trailing whitespace.  All of these are optional
  22.        and independently controllable.
  23.  
  24.        Provides a \'warn()\' method so you can generate warning messages that
  25.        report physical line number, even if the logical line in question
  26.        spans multiple physical lines.  Also provides \'unreadline()\' for
  27.        implementing line-at-a-time lookahead.
  28.  
  29.        Constructor is called as:
  30.  
  31.            TextFile (filename=None, file=None, **options)
  32.  
  33.        It bombs (RuntimeError) if both \'filename\' and \'file\' are None;
  34.        \'filename\' should be a string, and \'file\' a file object (or
  35.        something that provides \'readline()\' and \'close()\' methods).  It is
  36.        recommended that you supply at least \'filename\', so that TextFile
  37.        can include it in warning messages.  If \'file\' is not supplied,
  38.        TextFile creates its own using the \'open()\' builtin.
  39.  
  40.        The options are all boolean, and affect the value returned by
  41.        \'readline()\':
  42.          strip_comments [default: true]
  43.            strip from "#" to end-of-line, as well as any whitespace
  44.            leading up to the "#" -- unless it is escaped by a backslash
  45.          lstrip_ws [default: false]
  46.            strip leading whitespace from each line before returning it
  47.          rstrip_ws [default: true]
  48.            strip trailing whitespace (including line terminator!) from
  49.            each line before returning it
  50.          skip_blanks [default: true}
  51.            skip lines that are empty *after* stripping comments and
  52.            whitespace.  (If both lstrip_ws and rstrip_ws are false,
  53.            then some lines may consist of solely whitespace: these will
  54.            *not* be skipped, even if \'skip_blanks\' is true.)
  55.          join_lines [default: false]
  56.            if a backslash is the last non-newline character on a line
  57.            after stripping comments and whitespace, join the following line
  58.            to it to form one "logical line"; if N consecutive lines end
  59.            with a backslash, then N+1 physical lines will be joined to
  60.            form one logical line.
  61.          collapse_join [default: false]
  62.            strip leading whitespace from lines that are joined to their
  63.            predecessor; only matters if (join_lines and not lstrip_ws)
  64.  
  65.        Note that since \'rstrip_ws\' can strip the trailing newline, the
  66.        semantics of \'readline()\' must differ from those of the builtin file
  67.        object\'s \'readline()\' method!  In particular, \'readline()\' returns
  68.        None for end-of-file: an empty string might just be a blank line (or
  69.        an all-whitespace line), if \'rstrip_ws\' is true but \'skip_blanks\' is
  70.        not.'''
  71.     default_options = {
  72.         'strip_comments': 1,
  73.         'skip_blanks': 1,
  74.         'lstrip_ws': 0,
  75.         'rstrip_ws': 1,
  76.         'join_lines': 0,
  77.         'collapse_join': 0 }
  78.     
  79.     def __init__(self, filename = None, file = None, **options):
  80.         """Construct a new TextFile object.  At least one of 'filename'
  81.            (a string) and 'file' (a file-like object) must be supplied.
  82.            They keyword argument options are described above and affect
  83.            the values returned by 'readline()'."""
  84.         if filename is None and file is None:
  85.             raise RuntimeError, "you must supply either or both of 'filename' and 'file'"
  86.         
  87.         for opt in self.default_options.keys():
  88.             if options.has_key(opt):
  89.                 setattr(self, opt, options[opt])
  90.                 continue
  91.             setattr(self, opt, self.default_options[opt])
  92.         
  93.         for opt in options.keys():
  94.             if not self.default_options.has_key(opt):
  95.                 raise KeyError, "invalid TextFile option '%s'" % opt
  96.                 continue
  97.         
  98.         if file is None:
  99.             self.open(filename)
  100.         else:
  101.             self.filename = filename
  102.             self.file = file
  103.             self.current_line = 0
  104.         self.linebuf = []
  105.  
  106.     
  107.     def open(self, filename):
  108.         """Open a new file named 'filename'.  This overrides both the
  109.            'filename' and 'file' arguments to the constructor."""
  110.         self.filename = filename
  111.         self.file = open(self.filename, 'r')
  112.         self.current_line = 0
  113.  
  114.     
  115.     def close(self):
  116.         '''Close the current file and forget everything we know about it
  117.            (filename, current line number).'''
  118.         self.file.close()
  119.         self.file = None
  120.         self.filename = None
  121.         self.current_line = None
  122.  
  123.     
  124.     def gen_error(self, msg, line = None):
  125.         outmsg = []
  126.         if line is None:
  127.             line = self.current_line
  128.         
  129.         outmsg.append(self.filename + ', ')
  130.         if type(line) in (ListType, TupleType):
  131.             outmsg.append('lines %d-%d: ' % tuple(line))
  132.         else:
  133.             outmsg.append('line %d: ' % line)
  134.         outmsg.append(str(msg))
  135.         return string.join(outmsg, '')
  136.  
  137.     
  138.     def error(self, msg, line = None):
  139.         raise ValueError, 'error: ' + self.gen_error(msg, line)
  140.  
  141.     
  142.     def warn(self, msg, line = None):
  143.         '''Print (to stderr) a warning message tied to the current logical
  144.            line in the current file.  If the current logical line in the
  145.            file spans multiple physical lines, the warning refers to the
  146.            whole range, eg. "lines 3-5".  If \'line\' supplied, it overrides
  147.            the current line number; it may be a list or tuple to indicate a
  148.            range of physical lines, or an integer for a single physical
  149.            line.'''
  150.         sys.stderr.write('warning: ' + self.gen_error(msg, line) + '\n')
  151.  
  152.     
  153.     def readline(self):
  154.         '''Read and return a single logical line from the current file (or
  155.            from an internal buffer if lines have previously been "unread"
  156.            with \'unreadline()\').  If the \'join_lines\' option is true, this
  157.            may involve reading multiple physical lines concatenated into a
  158.            single string.  Updates the current line number, so calling
  159.            \'warn()\' after \'readline()\' emits a warning about the physical
  160.            line(s) just read.  Returns None on end-of-file, since the empty
  161.            string can occur if \'rstrip_ws\' is true but \'strip_blanks\' is
  162.            not.'''
  163.         if self.linebuf:
  164.             line = self.linebuf[-1]
  165.             del self.linebuf[-1]
  166.             return line
  167.         
  168.         buildup_line = ''
  169.         while None:
  170.             line = self.file.readline()
  171.             if line == '':
  172.                 line = None
  173.             
  174.             if self.strip_comments and line:
  175.                 pos = string.find(line, '#')
  176.                 if pos == -1:
  177.                     pass
  178.                 elif pos == 0 or line[pos - 1] != '\\':
  179.                     if not line[-1] == '\n' or '\n':
  180.                         pass
  181.                     eol = ''
  182.                     line = line[0:pos] + eol
  183.                     if string.strip(line) == '':
  184.                         continue
  185.                     
  186.                 else:
  187.                     line = string.replace(line, '\\#', '#')
  188.             
  189.             if self.join_lines and buildup_line:
  190.                 if line is None:
  191.                     self.warn('continuation line immediately precedes end-of-file')
  192.                     return buildup_line
  193.                 
  194.                 if self.collapse_join:
  195.                     line = string.lstrip(line)
  196.                 
  197.                 line = buildup_line + line
  198.                 if type(self.current_line) is ListType:
  199.                     self.current_line[1] = self.current_line[1] + 1
  200.                 else:
  201.                     self.current_line = [
  202.                         self.current_line,
  203.                         self.current_line + 1]
  204.             elif line is None:
  205.                 return None
  206.             
  207.             if type(self.current_line) is ListType:
  208.                 self.current_line = self.current_line[1] + 1
  209.             else:
  210.                 self.current_line = self.current_line + 1
  211.             if self.lstrip_ws and self.rstrip_ws:
  212.                 line = string.strip(line)
  213.             elif self.lstrip_ws:
  214.                 line = string.lstrip(line)
  215.             elif self.rstrip_ws:
  216.                 line = string.rstrip(line)
  217.             
  218.             if (line == '' or line == '\n') and self.skip_blanks:
  219.                 continue
  220.             
  221.             if self.join_lines:
  222.                 if line[-1] == '\\':
  223.                     buildup_line = line[:-1]
  224.                     continue
  225.                 
  226.                 if line[-2:] == '\\\n':
  227.                     buildup_line = line[0:-2] + '\n'
  228.                     continue
  229.                 
  230.             
  231.             return line
  232.  
  233.     
  234.     def readlines(self):
  235.         '''Read and return the list of all logical lines remaining in the
  236.            current file.'''
  237.         lines = []
  238.         while None:
  239.             line = self.readline()
  240.             if line is None:
  241.                 return lines
  242.             
  243.  
  244.     
  245.     def unreadline(self, line):
  246.         """Push 'line' (a string) onto an internal buffer that will be
  247.            checked by future 'readline()' calls.  Handy for implementing
  248.            a parser with line-at-a-time lookahead."""
  249.         self.linebuf.append(line)
  250.  
  251.  
  252. if __name__ == '__main__':
  253.     test_data = '# test file\n\nline 3 \\\n# intervening comment\n  continues on next line\n'
  254.     result1 = map((lambda x: x + '\n'), string.split(test_data, '\n')[0:-1])
  255.     result2 = [
  256.         '\n',
  257.         'line 3 \\\n',
  258.         '  continues on next line\n']
  259.     result3 = [
  260.         '# test file\n',
  261.         'line 3 \\\n',
  262.         '# intervening comment\n',
  263.         '  continues on next line\n']
  264.     result4 = [
  265.         'line 3 \\',
  266.         '  continues on next line']
  267.     result5 = [
  268.         'line 3   continues on next line']
  269.     result6 = [
  270.         'line 3 continues on next line']
  271.     
  272.     def test_input(count, description, file, expected_result):
  273.         result = file.readlines()
  274.         if result == expected_result:
  275.             print 'ok %d (%s)' % (count, description)
  276.         else:
  277.             print 'not ok %d (%s):' % (count, description)
  278.             print '** expected:'
  279.             print expected_result
  280.             print '** received:'
  281.             print result
  282.  
  283.     filename = 'test.txt'
  284.     out_file = open(filename, 'w')
  285.     out_file.write(test_data)
  286.     out_file.close()
  287.     in_file = TextFile(filename, strip_comments = 0, skip_blanks = 0, lstrip_ws = 0, rstrip_ws = 0)
  288.     test_input(1, 'no processing', in_file, result1)
  289.     in_file = TextFile(filename, strip_comments = 1, skip_blanks = 0, lstrip_ws = 0, rstrip_ws = 0)
  290.     test_input(2, 'strip comments', in_file, result2)
  291.     in_file = TextFile(filename, strip_comments = 0, skip_blanks = 1, lstrip_ws = 0, rstrip_ws = 0)
  292.     test_input(3, 'strip blanks', in_file, result3)
  293.     in_file = TextFile(filename)
  294.     test_input(4, 'default processing', in_file, result4)
  295.     in_file = TextFile(filename, strip_comments = 1, skip_blanks = 1, join_lines = 1, rstrip_ws = 1)
  296.     test_input(5, 'join lines without collapsing', in_file, result5)
  297.     in_file = TextFile(filename, strip_comments = 1, skip_blanks = 1, join_lines = 1, rstrip_ws = 1, collapse_join = 1)
  298.     test_input(6, 'join lines with collapsing', in_file, result6)
  299.     os.remove(filename)
  300.  
  301.